﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;


namespace SkinableFormsLib
{
    /// <summary>
    /// Extends TreeView component.
    /// On WM_PAINT it paints itself into an internal bitmap (from ILWControl) which is made transparent afterwards for usage in the layered window
    /// This model could be extended to simpler components (as LWLabel) if it's proven to be time efficient.
    /// </summary>
    public class LWTreeView : TreeView, ILWControl
    {
        private Bitmap _lwBitmap = null;
        private Rectangle _lwRectangle;
        private byte rc;
        private byte gc;
        private byte bc;


        private bool _lwTransparent = false;
        public bool LWTransparent
        {
            get
            {
                return _lwTransparent;
            }
            set
            {
                _lwTransparent = value;
                if (_lwTransparent)
                {
                    if (!DesignMode)
                        BackColor = Color.FromArgb(255,2, 2, 2);
                }
                else
                {
                    BackColor = _lwOriginalBackColor;
                }
            }
        }

        private Color _lwOriginalBackColor = Color.Transparent;
        public new Color BackColor
        {
            get
            {
                return base.BackColor;
            }
            set
            {
                base.BackColor = value;
                _lwOriginalBackColor = base.BackColor;
                rc = BackColor.R;
                gc = BackColor.G;
                bc = BackColor.B;

            }
        }


        /// <summary>
        /// Recomputes the internal Bitmap size
        /// </summary>
        /// <param name="e"></param>
        protected override void OnResize(System.EventArgs e)
        {
            if (_lwBitmap == null ||
                _lwBitmap.Width != Width || _lwBitmap.Height != Height)
            {

                if (Width != 0 && Height != 0)
                {
                    DisposeInternal();
                    _lwBitmap = new Bitmap(Width, Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                    _lwRectangle = new Rectangle(0, 0, _lwBitmap.Width, _lwBitmap.Height);
                }
            }
        }


        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);


           //if (m.Msg == Win32.WM_ERASEBKGND)//optional - needs more testing
            if (m.Msg == Win32.WM_PAINT)
            {
                if (!DesignMode)
                {
                    if (_lwBitmap == null)
                    {
                        OnResize(null);
                    }
                    this.DrawToBitmap(_lwBitmap, _lwRectangle);

                    if (_lwTransparent)
                    {
                        Utils.BitmapMakeTransparent(ref _lwBitmap, ref _lwRectangle, ref  bc, ref gc, ref  rc);
                        //or
                        //Utils.BitmapMakeTransparentUnsafe(ref _lwBitmap, ref _lwRectangle, ref  bc, ref gc, ref  rc); //I suspect this one is faster

                    }
                }
            }
        }


        private void DisposeInternal()
        {

            if (_lwBitmap != null)
                _lwBitmap.Dispose();

        }



        #region ILWControl Members

        Bitmap ILWControl.LWBitmap
        {
            get
            {

                return _lwBitmap;
            }
        }

        #endregion
    }
}
